// 随机生成n位字符串。可能包含数字和大小写字母
const generateRandomString = (length = 32) => {
    let result = '';
    
    for (let i = 0; i < length; i++) {
        // 随机决定字符类型：0-数字，1-大写字母，2-小写字母
        const charType = Math.floor(Math.random() * 3);
        let asciiCode;
        
        switch (charType) {
            case 0: // 数字 (48-57: '0'-'9')
                asciiCode = Math.floor(Math.random() * 10) + 48;
                break;
            case 1: // 大写字母 (65-90: 'A'-'Z')
                asciiCode = Math.floor(Math.random() * 26) + 65;
                break;
            case 2: // 小写字母 (97-122: 'a'-'z')
                asciiCode = Math.floor(Math.random() * 26) + 97;
                break;
        }
        
        result += String.fromCharCode(asciiCode);
    }
    
    return result;
}
/**
 * 获取当前用户ID的随机四位值
 */
const getUserId = (uid) => {
	if (!uid || uid.length < 4) {
		return generateRandomString(4)
	}
	var res = ''
	for (let i = 0; i < 4; i++) {
		res += uid[Math.floor(Math.random() * uid.length)]
	}
	return res
}

/**
 * 获取当前的年月日时分秒和毫秒
 * sortYear：是否只要后两位的年份
 */
const getTimeObj = (sortYear) => {
	const date = new Date()
	var year = date.getFullYear(),
		month = date.getMonth() + 1,
		day = date.getDate(),
		hour = date.getHours(),
		minute = date.getMinutes(),
		second = date.getSeconds(),
		msec = date.getMilliseconds(),
		week = date.getDay()
	year = year.toString()
	if (sortYear) {
		year = year.substr(-2)
	}
	if (month < 10) {
		month = '0' + month
	} else {
		month = month.toString()
	}
	if (day < 10) {
		day = '0' + day
	} else {
		day = day.toString()
	}
	if (hour < 10) {
		hour = '0' + hour
	} else {
		hour = hour.toString()
	}
	if (minute < 10) {
		minute = '0' + minute
	} else {
		minute = minute.toString()
	}
	if (second < 10) {
		second = '0' + second
	} else {
		second = second.toString()
	}
	if (msec < 10) {
		msec = '00' + msec
	} else if (msec < 100) {
		msec = '0' + msec
	} else {
		msec = msec.toString()
	}
	return {
		year, month, day, hour, minute, second, msec
	}
}
/**
 * 获取唯一的编码信息。一般都是后端生成
 * 取用户id中的随机四位，加上当前时间戳，再加上随机字母和数字，再加上校验码
 *
 * 当前时间戳，毫秒级
 * 生成规则：
 * 模式一：
 * 主要是两大部分
 * 第一部分是年月日时（根据时区的特点，精确到时可以修正日期）
 * 第二部分是分秒毫秒+随机字符
 * 24110112${编码前缀}-${项目前缀}3922742${用户ID}${随机字母}${随机数字}${校验码}
 * 
 * 模式二：
 * 获取当前的三位毫秒值
 * ${编码前缀}742${用户ID}${随机字母}${随机数字}${项目前缀}${校验码}
 * 
 * BM：编码前缀。一般是该类型名称的两位字母，比如前两个声母的首字母。默认是"BM"
 * XM：项目前缀。可以不传
 */
module.exports = (BM = 'BM', XM = '', type = 1, uid) => {
	const userId = getUserId(uid)
	const {year, month, day, hour, minute, second, msec} = getTimeObj(true)
	// 生成65-90之间的随机整数（A-Z的unicode编码范围）
	var unicode = Math.floor(Math.random() * 26) + 65
	var letter = String.fromCharCode(unicode)
	// 获取一位随机数字
	var number = Math.floor(Math.random() * 10)
	var string
	if (type === 1) {
		string = `${year}${month}${day}${hour}${BM}-${XM}${minute}${second}${msec}${userId}${letter}${number}`
	} else {
		string = `${BM}${msec}${userId}${letter}${number}${XM}`
	}
	/**
	 * 得到校验码
	 * 每一位的编码值加起来再同36（10个数字+26个大写字母）取余
	 */
	var res = 0
	for (let i = 0; i < string.length; i++) {
		res += string.charCodeAt(i)
	}
	res = res % 36
	if  (res > 10) {
		// 大于10的，转化为大写字母
		res -= 10
		res = String.fromCharCode(res + 65)
	}
	return string + res
}